/**
 * 
 */
package com.effectiv.gooruda.rest.service.api;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import lombok.Getter;

import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;


import com.effectiv.gooruda.rest.docs.annotation.Api;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeader;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeaders;
import com.effectiv.gooruda.rest.docs.annotation.ApiMethod;

import com.effectiv.gooruda.rest.docs.annotation.ApiResponseObject;
import com.effectiv.gooruda.rest.docs.pojo.ApiVerb;
import com.effectiv.gooruda.rest.domain.FileStorage;
import com.effectiv.gooruda.rest.ext.ExtResponse;
import com.effectiv.gooruda.rest.ext.SecurityContextHolder;


/**
 * @author Dhrubo
 *
 */
@Api(name = "File Storage API", description = "Upload and manage files.")
@Path("/file")
public abstract class FileStorageService {
	
	@Getter
	@Autowired
	private MongoTemplate mongoTemplate;
	
	@Getter
	@Autowired
	private GridFsTemplate gridFsTemplate;

	private final String COLLECTION_BASE = "t_app_storage_";
	
	protected String getCollection(){
		return COLLECTION_BASE + SecurityContextHolder.get().getId();
	}
	
	protected String getAppFileName(String fileName, String folder){
		return "/" + SecurityContextHolder.get().getId() + "/"
				+ folder + "/" + fileName;
	}
	
	protected void throwException(int errorCode, String errorMessage){
		ExtResponse extRes = new ExtResponse();
		extRes.setErrorCode(errorCode);
		extRes.setMessage(errorMessage);
		
		ResponseBuilder resBuilder = Response.status(Status.BAD_REQUEST);
		resBuilder.entity(extRes);
		
		throw new WebApplicationException(resBuilder.build());
	}
	
	
	@ApiMethod(path = "/api/file/", verb = ApiVerb.POST, description = "Upload a file in a folder.")
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	
	@POST
	@Consumes("multipart/form-data")
	public abstract @ApiResponseObject Response store(@MultipartForm FileStorage storage);
	
	
	
	@ApiMethod(path = "/api/file/update", verb = ApiVerb.POST, description = "Update a file with a newer version.")
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	
	@Path("/update")
	@POST
	@Consumes("multipart/form-data")
	public abstract @ApiResponseObject Response  update(
			@MultipartForm FileStorage storage);
	
	
	public abstract @ApiResponseObject Response  addTags(String fileName, String folder,  String tags);
	public abstract @ApiResponseObject Response  removeTags(String fileName, String folder, String tags);
	public abstract @ApiResponseObject Response  removeAllTags(String fileName,  String folder);
	
	public abstract @ApiResponseObject Response  removeOwner(String fileName, String folder);
	public abstract @ApiResponseObject Response  changeOwner(String fileName, String folder, String oldOwner, String newOwner);
	
	
	public abstract @ApiResponseObject Response  moveFolder(String fileName, String oldFolder, String newFolder);
	
	
	public abstract @ApiResponseObject Response  deleteFolder(String folder);
	public abstract @ApiResponseObject Response  renameFolder(String oldFolder, String newFolder);
	
	public abstract @ApiResponseObject Response  deleteByUser(String userName);
	public abstract @ApiResponseObject Response  deleteByName(String fileName);
	public abstract @ApiResponseObject Response  deleteAllByUser(String userName);
	public abstract @ApiResponseObject Response  deleteAll();
	
	public abstract @ApiResponseObject Response  countByType(String type);
	public abstract @ApiResponseObject Response  countByUser(String userName);
	public abstract @ApiResponseObject Response  count();
	
	public abstract @ApiResponseObject Response  findByType(String type, Pageable page);
	public abstract @ApiResponseObject Response  findByOwner(String userName, Pageable page);
	public abstract @ApiResponseObject Response  findAll(Pageable page);
	public abstract @ApiResponseObject Response  findByTags(String tags[], Pageable page);
	
	public abstract @ApiResponseObject Response  download(String fileName);
	
	public abstract @ApiResponseObject Response  findByName(String fileName, Pageable page);
	
	
}
